package com.enjoyor.soa.traffic.util.helper;

import org.apache.commons.net.ftp.FTPClient;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.io.*;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@SuppressWarnings("restriction")
public final class ImageHelper {

	public static byte[] getImageBytes(String fileContent) {
		BASE64Decoder decoder = new BASE64Decoder();
		byte[] bytes = null;
		try {
			bytes = decoder.decodeBuffer(fileContent);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return bytes;
	}

	@SuppressWarnings("resource")
	public static byte[] getImageBytes(File file) throws IOException {
		byte[] bytes = new byte[(int) (file.length())];
		BufferedInputStream bufferStream;
		try {
			bufferStream = new BufferedInputStream(new FileInputStream(file));
			int r = bufferStream.read(bytes);
			if (r != file.length()) {
				throw new IOException("读取文件不正确");
			}
			bufferStream.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return bytes;
	}
	
	
	/**
	 * 图片转化成base64字符串  
	 * @param imgFile
	 * @return
	 * @throws InterruptedException
	 * @throws FileNotFoundException
	 */
    public static String GetImageStr(String imgFile) throws InterruptedException, FileNotFoundException  
    {
    	imgFile = imgFile.replaceAll("\\\\", "/");
    	int from = 0;
    	//将图片文件转化为字节数组字符串，并对其进行Base64编码处理  
    	String base64 = "";

        //对字节数组Base64编码  
        BASE64Encoder encoder = new BASE64Encoder(); 
        
        InputStream in = null;  
        byte[] data = null; 
	        //读取图片字节数组  
	    try   
	    {  
	        in = new FileInputStream(imgFile);          
	        data = new byte[in.available()];  
	        in.read(data);  
	        in.close();  
	    }   
	    catch (IOException e)   
	    {  
	          //  e.printStackTrace();  
	    } 
	        
	    if(data != null)
	    	base64 = org.apache.commons.codec.binary.Base64.encodeBase64String(data);
      
        return base64;//返回Base64编码过的字节数组字符串  
    }
    
    /**
	 * 从ftp获取图片转化成base64字符串  
	 * @param imgFile
	 * @return
	 * @throws InterruptedException
	 * @throws FileNotFoundException
	 */
    
    public static String GetImageStrFromFtp(String imgFtpFile, String tempPath) throws InterruptedException, FileNotFoundException  
    {
    	Map<String, String> ftpmap = getFtpInfo(imgFtpFile);
    	FTPClient ftp = new FTPClient();
    	//将图片文件转化为字节数组字符串，并对其进行Base64编码处理  
    	String base64 = "";

        //对字节数组Base64编码  
        BASE64Encoder encoder = new BASE64Encoder(); 
        
        InputStream in = null;  
        byte[] data = null;   
        String[] temp = ftpmap.get("name").split("/"); 
	        //读取图片字节数组  
	    try   
	    {  
            ftp.connect(ftpmap.get("url"),Integer.valueOf(ftpmap.get("port")));
            ftp.login(ftpmap.get("user"),ftpmap.get("pwd"));
            ftp.setCharset(Charset.forName("UTF-8"));
            ftp.setControlEncoding("UTF-8");
            in = ftp.retrieveFileStream(ftpmap.get("name")); 
            FileOutputStream fos = new FileOutputStream(new File(tempPath+temp[temp.length-1]));

            byte[] b = new byte[1024];
            int len = 0;
            while ((len = in.read(b)) != -1) {
                fos.write(b,0,len);
            }
	        in.close(); 
	        ftp.completePendingCommand();
			ftp.logout();
			ftp.disconnect();
			ftp = null;
			in = new FileInputStream(tempPath+temp[temp.length-1]);          
	        data = new byte[in.available()];  
	        in.read(data);  
	        in.close();  
	        fos.close();
	    }   
	    catch (IOException e)   
	    {  
	          //  e.printStackTrace();  
	    }finally{
	        FileHelper.delete(tempPath+temp[temp.length-1]);

	    } 
	        
	    if(data != null){
	    	base64 = encoder.encode(data);
	    }
      
        return base64;//返回Base64编码过的字节数组字符串  
    }
	
	
	/**
	 * base64转换成图片存至本地磁盘
	 * @param base64Str 
	 * @param fileName
	 * @return
	 */
	public static String GenerateImage(String base64Str,String filePath, String fileName)  
    {   //对字节数组字符串进行Base64解码并生成图片  
    	
        if (base64Str == null) //图像数据为空  
            return "";  
        BASE64Decoder decoder = new BASE64Decoder();  
        try   
        {  
            //文件路径
            String dir="";
            
            //Base64解码  
            byte[] b = decoder.decodeBuffer(base64Str);  
            for(int i=0;i<b.length;++i)  
            {  
               if(b[i]<0)  
               {//调整异常数据  
                    b[i]+=256;  
               }  
            }  
            //生成文件夹
	        
	        makeDir(filePath);
            //生成jpeg图片  
	        if(!fileName.contains(".jpg") && !fileName.contains(".JPG")
	        		 && !fileName.contains(".png") && !fileName.contains(".PNG")
	        		 && !fileName.contains(".bmp") && !fileName.contains(".BMP"))
	        	fileName = fileName+".jpg";
            String imgFilePath = filePath+fileName;//新生成的图片  
            dir = imgFilePath;
            OutputStream out = new FileOutputStream(imgFilePath);      
            out.write(b);  
            out.flush();  
            out.close();
            return dir;  
        }   
        catch (Exception e)   
        {  
            return "";  
        }  
    }
	
	public static String GenerateFile(String base64Str,String filePath, String fileName)  
    {   //对字节数组字符串进行Base64解码并生成图片  
    	
        if (base64Str == null) //图像数据为空  
            return "";  
        BASE64Decoder decoder = new BASE64Decoder();  
        try   
        {  
            //文件路径
            String dir="";
            
            //Base64解码  
            byte[] b = decoder.decodeBuffer(base64Str);  
            for(int i=0;i<b.length;++i)  
            {  
               if(b[i]<0)  
               {//调整异常数据  
                    b[i]+=256;  
               }  
            }  
            //生成文件夹
	        
	        makeDir(filePath);
            //生成jpeg图片  
            String imgFilePath = filePath+fileName;//新生成的图片  
            dir = imgFilePath;
            OutputStream out = new FileOutputStream(imgFilePath);      
            out.write(b);  
            out.flush();  
            out.close();
            return dir;  
        }   
        catch (Exception e)   
        {  
            return "";  
        }  
    }
	
	/**
	 * 移动到最里层文件夹，没有新建
	 * @param dirPath
	 */
	public static void makeDir(String dirPath)
    {
    	File file =new File(dirPath);  
    	if  (!file .exists()  && !file .isDirectory())      
    	{       
    	 //   log.info("文件夹不存在，创建文件夹");
    	    file.mkdirs();    
    	} else   
    	{   
    	}  
    }
    
	/**
	 * ftp上移动到最里层文件夹，没有新建
	 * @param dirPath
	 * @param ftpClient
	 */
    public static void makeDir(String dirPath,FTPClient ftpClient)
    {
        String tempDirPath = dirPath.substring(0,dirPath.length());
        String[] dirPathArr = tempDirPath.split("/");
        String dir = "";
        for (String dp : dirPathArr)
        {
            try
            {
                if(!ftpClient.changeWorkingDirectory(dp))
                {
                    dir+=dp+"/";
                    ftpClient.makeDirectory(dir);
                }
            }
            catch (IOException e)
            {
          //      log.error("文件夹创建失败！");
                e.printStackTrace();
            }
        }
    }
    
  //从文件路径获取ftp地址参数
    public static  Map<String,String> getFtpInfo(String ftpstr){
  			Map<String,String> map = new HashMap();
  			
  			if(ftpstr.indexOf("ftp") > -1){
  				String top = ftpstr.substring(6,ftpstr.length()).split("/")[0];
  				String name = ftpstr.replace("ftp://"+top,"");
  				map.put("name", name);
  				map.put("path", "ftp://"+top);
  				String userpwd = top.split("@")[0];
  				String urlport = top.split("@")[1];
  				map.put("user", userpwd.split(":")[0]);
  				map.put("pwd", userpwd.split(":")[1]);
  				map.put("url", urlport.split(":")[0]);
  				if(urlport.split(":").length>1){
  					map.put("port", urlport.split(":")[1]);
  				}else
  					map.put("port", "21");
  			}
  			
  			return map;
  		}

    /**
     * 
     * getImageStr4Cut(裁剪图片，并进行尺寸和质量的压缩)   
     * @param path 图片路径
     * @param index 图片裁剪区域,-1代表整张图
     * @return String  图片Base64编码字符串
     * @since  1.0.0
     */
    public static String getImageStr4Cut(String path,int index)
    {
        byte[] fileData = null;
        BASE64Encoder encoder = new BASE64Encoder();
        try
        {
            URL url1 = new URL(path);
            BufferedImage targetImage = null;
            BufferedImage tempImage = null;
            BufferedImage srcImage = ImageIO.read(url1);
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ImageIO.write(srcImage, "jpg", out);
            byte[] b = out.toByteArray();
            //截图，取左上、左下和右右上三张图片
            if(index == -1)
            {
                targetImage =  srcImage.getSubimage(0, 0, srcImage.getWidth(), srcImage.getHeight());
            }
            if(index == 0)
            {
                targetImage =  srcImage.getSubimage(0, 0, srcImage.getWidth()/2, srcImage.getHeight()/2);
            }
            if(index == 1)
            {
                targetImage =  srcImage.getSubimage(srcImage.getWidth()/2, 0, srcImage.getWidth()/2, srcImage.getHeight()/2);
            }
            if(index == 2)
            {
                targetImage =  srcImage.getSubimage(0, srcImage.getHeight()/2, srcImage.getWidth()/2, srcImage.getHeight()/2);
            }
            //按照指定尺寸缩放比例压缩图片
            System.out.println(srcImage.getWidth());
            if(srcImage.getWidth()>300)
            	tempImage = toSmallerPic(targetImage,(float) 300/srcImage.getWidth());
            else
            	tempImage = toSmallerPic(targetImage,(float) 0.8);
            
            if(b.length>0&& b.length <= 1024*1024)
            {
                fileData = bufferedImageTobytes(tempImage,(float) 0.28);
            }
            else if(b.length>1024*1024 && b.length < 1024*1024*2)
            {
                fileData = bufferedImageTobytes(tempImage,(float) 0.15);
            }
            else if(b.length>1024*1024*2 && b.length < 1024*1024*3)
            {
                fileData = bufferedImageTobytes(tempImage,(float) 0.10);
            }
            else if(b.length>1024*1024*3)
            {
                fileData = bufferedImageTobytes(tempImage,(float) 0.05);
            }
            
            b = null;
            srcImage = null;
            targetImage = null;
            tempImage = null;
            out.close();
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        return encoder.encode(fileData);
      //  return fileData;
    }
    
    /**
     * toSmallerPic(将BufferedImage按照尺寸缩放比例进行压缩)   
     * @param srcImage 源图片
     * @param ratio 缩放比例
     * @return BufferedImage   
     * @exception    
     * @since  1.0.0
     */
    public static BufferedImage toSmallerPic(BufferedImage srcImage,float ratio)
    {
        //源图宽
        int old_w = srcImage.getWidth();
        //源图长
        int old_h = srcImage.getHeight();
        //新图宽
        int new_w = old_w;
        //新图长
        int new_h = old_h;
        //生成新图片
        BufferedImage tempImg = new BufferedImage(old_w, old_h,BufferedImage.TYPE_INT_RGB);
        Graphics2D g = tempImg.createGraphics();
        g.setColor(Color.white);
        // 从原图上取颜色绘制新图g.fillRect(0, 0, old_w, old_h);
        g.drawImage(srcImage, 0, 0, old_w, old_h, Color.white, null);
        g.dispose();
        // 根据图片尺寸压缩比得到新图的尺寸
        new_w = (int) Math.round(old_w * ratio);
        new_h = (int) Math.round(old_h * ratio);
        BufferedImage newImg = new BufferedImage(new_w, new_h,BufferedImage.TYPE_INT_RGB);
        newImg.getGraphics().drawImage(tempImg.getScaledInstance(new_w, new_h, Image.SCALE_SMOOTH), 0,0, null);
        return newImg;
    }
    
    /**
     * getImageStr4Full()   
     * @param path
     * @return String   
     * @exception    
     * @since  1.0.0
     */
    public static String getImageStr4Full(String path)
    {
        byte[] fileData = null;
        BASE64Encoder encoder = new BASE64Encoder();
        try
        {
            URL url1 = new URL(path);
            BufferedImage srcImage = ImageIO.read(url1);
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ImageIO.write(srcImage, "jpg", out);
            byte[] b = out.toByteArray();
            BufferedImage tempImage = toSmallerPic(srcImage, 1);
            fileData = bufferedImageTobytes(tempImage,1);
           
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        return encoder.encode(fileData);
    }
    
    
    
    /**
     * 
     * bufferedImageTobytes(BufferedImage转换成字节数据,并进行图片质量压缩)   
     * @param image  BufferedImage对象
     * @param quality 图片质量压缩比例
     * @return byte[]   
     * @exception    
     * @since  1.0.0
     */
    public static byte[] bufferedImageTobytes(BufferedImage image, float quality) {  
        // 如果图片空，返回空  
        if (image == null) {  
            return null;  
        }  
        // 得到指定Format图片的writer  
        Iterator<ImageWriter> iter = ImageIO.getImageWritersByFormatName("jpg");// 得到迭代器  
        ImageWriter writer = (ImageWriter) iter.next(); // 得到writer  
        // 得到指定writer的输出参数设置(ImageWriteParam )  
        ImageWriteParam iwp = writer.getDefaultWriteParam();  
        iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); // 设置可否压缩  
        iwp.setCompressionQuality(quality); // 设置压缩质量参数  
        iwp.setProgressiveMode(ImageWriteParam.MODE_DISABLED);  
        ColorModel colorModel = ColorModel.getRGBdefault();  
        // 指定压缩时使用的色彩模式  
        iwp.setDestinationType(new javax.imageio.ImageTypeSpecifier(colorModel,colorModel.createCompatibleSampleModel(16, 16)));
        // 开始打包图片，写入byte[]  
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); // 取得内存输出流  
        IIOImage iIamge = new IIOImage(image, null, null);  
        try {  
            // 此处因为ImageWriter中用来接收write信息的output要求必须是ImageOutput  
            // 通过ImageIo中的静态方法，得到byteArrayOutputStream的ImageOutput  
            writer.setOutput(ImageIO.createImageOutputStream(byteArrayOutputStream));  
            writer.write(null, iIamge, iwp);  
        } catch (IOException e) {  
            System.out.println("write error");  
            e.printStackTrace();  
        }  
        return byteArrayOutputStream.toByteArray();  
    }
    @SuppressWarnings("unchecked")
    public boolean xmlToMap(Map<String,Object> resultMap)
    {
        boolean flag = false;
        Map<String,String> headMap = (Map<String, String>) resultMap.get("head");
        if("1".equals(headMap.get("code")))
        {
            flag = true;
        }
        else
        {
            flag = false;
        }
        return flag;
    }
    
}
